package com.xjrsoft.module.liteflow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.module.generator.utils.GeneratorUtil;
import com.xjrsoft.module.liteflow.dto.AddLiteflowCodeDto;
import com.xjrsoft.module.liteflow.dto.UpdateLiteflowCodeDto;
import com.xjrsoft.module.liteflow.entity.LiteflowCode;
import com.xjrsoft.module.liteflow.mapper.LiteflowCodeMapper;
import com.xjrsoft.module.liteflow.service.ILiteflowCodeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

/**
 * <p>
 * 规则代码表 服务实现类
 * </p>
 *
 * @author hnyyzy
 * @since 2024-05-17
 */
@Service
@AllArgsConstructor
public class LiteflowCodeServiceImpl extends ServiceImpl<LiteflowCodeMapper, LiteflowCode> implements ILiteflowCodeService {

    private final LiteflowCodeMapper codeMapper;

    @Override
    public boolean addCode(AddLiteflowCodeDto dto) {
        Long count = codeMapper.selectCount(Wrappers.<LiteflowCode>lambdaQuery().eq(LiteflowCode::getCodeNumber, dto.getCodeNumber()).or().eq(LiteflowCode::getMethodName, dto.getMethodName()));
        if (count > 0){
            throw new MyException("规则方法名或者代码编号已存在！");
        }
        LiteflowCode liteflowCode = BeanUtil.toBean(dto, LiteflowCode.class);
        //文件内容
        String fileValue = dto.getCodeData();
        //获取到类名
        String className = getClassNameFromCode(fileValue);
        //生成文件名
        String fileName = className + StringPool.DOT_JAVA;
        //获取到包路径
        String packageName = getPackageNameInFirstLine(fileValue);
        //文件生成路径
        String dirPath =  System.getProperty("user.dir") + StringPool.SLASH + "src" + StringPool.SLASH + "main" + StringPool.SLASH + "java" + StringPool.SLASH + packageName;
        try {
            //生成对应的文件
            GeneratorUtil.writeFile(dirPath,fileName,fileValue);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        return codeMapper.insert(liteflowCode) > 0;
    }

    @Override
    public boolean updateCode(UpdateLiteflowCodeDto dto) {
        Long count = codeMapper.selectCount(Wrappers.<LiteflowCode>lambdaQuery().eq(LiteflowCode::getCodeNumber, dto.getCodeNumber()).ne(LiteflowCode::getId,dto.getId())
                .or().eq(LiteflowCode::getMethodName, dto.getMethodName()).ne(LiteflowCode::getId,dto.getId()));
        if (count > 0){
            throw new MyException("规则方法名或者代码编号已存在！");
        }
        LiteflowCode liteflowCode = BeanUtil.toBean(dto, LiteflowCode.class);
        //通过id找到原本的文件名称
        LiteflowCode oldCode = codeMapper.selectById(dto.getId());
        //文件内容
        String oldFileValue = oldCode.getCodeData();
        //获取到类名
        String oldClassName = getClassNameFromCode(oldFileValue);
        //生成文件名
        String oldFileName = oldClassName + StringPool.DOT_JAVA;
        //获取到包路径
        String oldPackageName = getPackageNameInFirstLine(oldFileValue);
        //文件生成路径
        String oldDirPath =  System.getProperty("user.dir") + StringPool.SLASH + "src" + StringPool.SLASH + "main" + StringPool.SLASH + "java" + StringPool.SLASH +oldPackageName;
        String oldFilePath = oldDirPath + StringPool.SLASH + oldFileName;
        //删除原本的文件
        // 创建File对象
        File file = new File(oldFilePath);
        // 判断文件是否存在
        if (file.exists()) {
            // 文件存在则尝试删除
            boolean deleted = file.delete();
            if (deleted) {
                System.out.println("文件删除成功：" + oldFilePath);
            } else {
                System.out.println("文件删除失败：" + oldFilePath);
            }
        } else {
            System.out.println("文件不存在：" + oldFilePath);
        }

        //文件内容
        String fileValue = dto.getCodeData();
        //获取到类名
        String className = getClassNameFromCode(fileValue);
        //生成文件名
        String newFileName = className + StringPool.DOT_JAVA;
        //获取到包路径
        String packageName = getPackageNameInFirstLine(fileValue);
        //文件生成路径
        String dirPath =  System.getProperty("user.dir") + StringPool.SLASH + "src" + StringPool.SLASH + "main" + StringPool.SLASH + "java" + StringPool.SLASH +packageName;
        try {
            //生成对应的文件
            GeneratorUtil.writeFile(dirPath,newFileName,fileValue);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        return codeMapper.updateById(liteflowCode) > 0;
    }

    @Override
    public boolean deleteCode(List<Long> ids) {
        //先根据id查出之前的数据
        List<LiteflowCode> liteflowCodeList = codeMapper.selectList(Wrappers.<LiteflowCode>lambdaQuery().in(LiteflowCode::getId, ids));
        for (LiteflowCode liteflowCode : liteflowCodeList) {
            //文件内容
            String fileValue = liteflowCode.getCodeData();
            //获取到类名
            String className = getClassNameFromCode(fileValue);
            //生成文件名
            String fileName = className + StringPool.DOT_JAVA;
            //获取到包路径
            String packageName = getPackageNameInFirstLine(fileValue);
            //文件生成路径
            String dirPath =  System.getProperty("user.dir") + StringPool.SLASH + "src" + StringPool.SLASH + "main" + StringPool.SLASH + "java" + StringPool.SLASH + packageName;
            String filePath = dirPath + StringPool.SLASH + fileName;
            // 创建File对象
            File file = new File(filePath);
            // 判断文件是否存在
            if (file.exists()) {
                // 文件存在则尝试删除
                boolean deleted = file.delete();
                if (deleted) {
                    System.out.println("文件删除成功：" + filePath);
                } else {
                    System.out.println("文件删除失败：" + filePath);
                }
            } else {
                System.out.println("文件不存在：" + filePath);
            }
        }
        return codeMapper.deleteBatchIds(ids) > 0;
    }

    /** 根据java文件第一行获取包名 */
    public static String getPackageNameInFirstLine(String code){
        return code
                .substring(0,code.indexOf(";"))
                .replace("package ", "")
                .replaceAll("\\.", "/");
    }

    /** 从java String字符串中获取类名 */
    public static String getClassNameFromCode(String code){
        int classBlank = code.indexOf("class ")+6;
        String className = code.substring(classBlank);
        int nextBlank = className.indexOf(" ");
        className = className.substring(0,nextBlank);
        if(className.contains("{")){
            int i = className.indexOf("{");
            className = className.substring(0,i);
        }
        return className;
    }

}
